package lion.bugrambo.execution;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;

import lion.bugrambo.BugRamboConsts.BUGLEVEL;
import lion.bugrambo.BugRamboConsts.BUGSOLVETYPE;
import lion.bugrambo.model.Bug;
import lion.bugrambo.model.Project;
import lion.bugrambo.model.ProjectModel;
import lion.dev.lang.MapJ;
import lion.dev.text.Formater;
import lion.dev.web.Validator;
import lion.dev.web.paging.PagedVo;
import lion.framework.core.db.DB;
import lion.framework.core.db.DataTable;
import lion.framework.core.db.SQLJoin;
import lion.framework.core.db.SessionFactory;
import lion.framework.core.db.paging.SQLPagingFactory;
import lion.framework.core.web.anno.Namespace;
import lion.framework.core.web.anno.Path;
import lion.framework.core.web.anno.Result;
import lion.framework.core.web.anno.View;
import lion.framework.core.web.request.Request;
import lion.framework.core.web.views.ResultType;
import lion.web.constant.Const.TODO;
import lion.web.export.ExcelExporter;
import lion.web.platform.model.User;
import lion.web.platform.model.UserFile;
import lion.web.platform.model.UserTodo;
import lion.web.platform.priv.user.LoginUser;

/**
 * 缺陷管理
 * 
 * @author lion
 * @email hl_0074@sina.com
 * @date 2015年4月3日
 */
@Namespace("#{admin}/br")
public class BugExecution {

	@Path("/bugs")
	@Result(@View("/WEB-INF/template/bugrambo/bugs/index.jsp"))
	public String index(Request request) {

		return "success";
	}

	@Path("/bugs/list")
	@Result(@View(type = ResultType.JSON))
	public String list(Request request) {

		int page = request.getInt("page", 1);
		int size = request.getInt("size", 30);

		SQLJoin sqlJoin = new SQLJoin();
		sqlJoin.add("projectId=:projectId");
		int owner = request.getInt("owner");
		if (owner > 0) {
			sqlJoin.add("owner=:owner");
		}
		int modelId = request.getInt("modelId");
		if (modelId > 0) {
			sqlJoin.add("modelId=:modelId");
		}
		int bugStatus = request.getInt("bugStatus");
		if (bugStatus > 0) {
			sqlJoin.add("bugStatus=:bugStatus");
		}
		int level = request.getInt("level");
		if (level > 0) {
			sqlJoin.add("level=:level");
		}
		int bugId = request.getInt("bugId");
		if (bugId > 0) {
			sqlJoin.add("id=:bugId");
		}

		PagedVo<MapJ> pagedVo = new PagedVo<>(Bug.count("where " + sqlJoin.toString(), request));
		pagedVo.getPaging().setPageNumber(page);
		pagedVo.getPaging().setPageSize(size);

		String sql1 = "select b.*,(select realName from User u where u.id=b.owner) ownerName,(select realName from User u where u.id=b.creator) creatorName,(select realName from User u where u.id=b.solveAccId) solveAccName,(select realName from User u where u.id=b.closeAccId) closeAccName  from Bug b";

		String sort = request.getString("col");
		String order = request.getString("order");

		if (StringUtils.isBlank(sort)) {
			sort = "id";
		}
		sqlJoin.addSort(sort, order);

		sql1 += " where " + sqlJoin.toString();

		DB db = SessionFactory.getCurrentDB();
		DataTable dt = db.query(SQLPagingFactory.paging(db.getType(), sql1, pagedVo.getPaging().getStartRowNumber(), pagedVo.getPaging().getPageSize()), request);

		pagedVo.setVos(dt.getRows());

		request.addModel("vos", pagedVo.getVos());
		request.addModel("paging", pagedVo.getPaging());

		return "success";
	}

	@Path("/bugs/edit")
	@Result(@View("/WEB-INF/template/bugrambo/bugs/edit.jsp"))
	public String edit(Request request) {

		int projectId = request.getInt("projectId");
		int id = request.getInt("id");
		if (id > -1) {
			Bug bug = Bug.load(id);
			if (bug != null) {
				request.addModel("bug", bug);
				projectId = bug.getProjectId();

				request.addModel("owner", User.load(bug.getOwner()));

				if (StringUtils.isNotBlank(bug.getAttachs())) {
					request.addModel("attaches", UserFile.list(-1, "where id in(" + bug.getAttachs() + ")"));
				}
			}
		}

		request.addModel("projectId", projectId);

		return "success";
	}

	@Path("/bugs/save")
	@Result(@View(type = ResultType.JSON))
	public String save(Request request) {

		Bug bug = Bug.create(request);
		bug.setCreator(LoginUser.current().getUser().getId());
		bug.setCreateTime(new Date());
		bug.setBugStatus(1);
		bug.setLogs("bug created by " + LoginUser.current().getUser().getRealName() + "(" + LoginUser.current().getUser().getName() + ") at "
				+ Formater.formatDate("yyyy-MM-dd HH:mm:ss", new Date()));

		bug.save();

		return "success";
	}

	@Path("/bugs/update")
	public void update(Request request) {

		Bug bug = Bug.load(request.getInt("id"));

		if (bug == null) { return; }

		bug.setBugStatus(request.getInt("bugStatus"));
		bug.setDescription(request.getString("description"));
		bug.setLevel(request.getInt("level"));
		bug.setModelId(request.getInt("modelId"));
		bug.setTitle(request.getString("title"));
		bug.setOwner(request.getInt("owner"));
		bug.setAttachs(request.getString("attachs"));

		int bugStatus = request.getInt("bugStatus");

		String logs = bug.getLogs();
		if (bugStatus != bug.getSolveType()) {
			if (bugStatus == 2) {// 解决
				logs = "Bug solved by " + LoginUser.current().getUser().getRealName() + "(" + LoginUser.current().getUser().getName() + ") "
						+ Formater.formatDate("yyyy-MM-dd HH:mm:ss", new Date()) + "\n" + logs;
				bug.setBugStatus(2);
				bug.setSolveType(request.getInt("solveType"));
				bug.setSolveTime(new Date());
				bug.setSolveAccId(LoginUser.current().getUser().getId());

			} else if (bugStatus == 3) {// 关闭
				logs = "Bug closed by " + LoginUser.current().getUser().getRealName() + "(" + LoginUser.current().getUser().getName() + ") "
						+ Formater.formatDate("yyyy-MM-dd HH:mm:ss", new Date()) + "\n" + logs;
				bug.setBugStatus(3);
				bug.setCloseAccId(LoginUser.current().getUser().getId());
				bug.setCloseTime(new Date());
			} else if (bugStatus == 1) { // 重新打开
				logs = "Bug open by " + LoginUser.current().getUser().getRealName() + "(" + LoginUser.current().getUser().getName() + ") "
						+ Formater.formatDate("yyyy-MM-dd HH:mm:ss", new Date()) + "\n" + logs;
				bug.setBugStatus(1);
				bug.setCloseAccId(-1);
				bug.setCloseTime(null);
				bug.setSolveAccId(-1);
				bug.setSolveTime(null);
				bug.setSolveType(-1);
			}
		} else {
			logs = "Bug update by " + LoginUser.current().getUser().getRealName() + "(" + LoginUser.current().getUser().getName() + ") "
					+ Formater.formatDate("yyyy-MM-dd HH:mm:ss", new Date()) + "\n" + logs;
		}
		bug.setLogs(logs);

		bug.update();
	}

	@Path("/bugs/delete")
	public void delete(Request request) {

		int[] ids = Validator.toIntArray(request.getString("ids"));
		if (ids.length == 0) { return; }

		Bug.delete(ids);
	}

	@Path("/bugs/export")
	@Result(@View(type = "excel"))
	public String export(Request request) {

		SQLJoin sqlJoin = new SQLJoin();
		sqlJoin.add("projectId=:projectId");
		int owner = request.getInt("owner");
		if (owner > 0) {
			sqlJoin.add("owner=:owner");
		}
		int modelId = request.getInt("modelId");
		if (modelId > 0) {
			sqlJoin.add("modelId=:modelId");
		}
		int bugStatus = request.getInt("bugStatus");
		if (bugStatus > 0) {
			sqlJoin.add("bugStatus=:bugStatus");
		}
		int level = request.getInt("level");
		if (level > 0) {
			sqlJoin.add("level=:level");
		}
		int bugId = request.getInt("bugId");
		if (bugId > 0) {
			sqlJoin.add("id=:bugId");
		}

		String sql1 = "select b.*,(select realName from User u where u.id=b.owner) ownerName,(select realName from User u where u.id=b.creator) creatorName,(select realName from User u where u.id=b.solveAccId) solveAccName,(select realName from User u where u.id=b.closeAccId) closeAccName  from Bug b ";
		sql1 += " where " + sqlJoin.toString();

		DB db = SessionFactory.getCurrentDB();
		DataTable dt = db.query(sql1, request);

		List<MapJ> rows = dt.getRows();
		for (MapJ row : rows) {

			row.put("level", BUGLEVEL.getLevelName(row.getInt("level")));
			row.put("bugStatus", BUGLEVEL.getLevelName(row.getInt("level")));
			row.put("solveType", BUGSOLVETYPE.getTypeName(row.getInt("solveType")));

			row.put("createTime", Formater.formatDate("yyyy-MM-dd HH:mm:ss", row.getDate("createTime")));
			row.put("solveTime", Formater.formatDate("yyyy-MM-dd HH:mm:ss", row.getDate("solveTime")));
			row.put("closeTime", Formater.formatDate("yyyy-MM-dd HH:mm:ss", row.getDate("closeTime")));
		}

		Workbook workbook = ExcelExporter.create("Bug列表", dt.getRows(),
				new String[][] { { "id", "ID" }, { "level", "等级" }, { "title", "标题" }, { "bugStatus", "状态" }, { "ownerName", "指派给" }, { "creatorName", "创建者" },
						{ "createTime", "创建时间" }, { "solveAccName", "解决者" }, { "solveTime", "解决时间" }, { "solveType", "解决方案" }, { "closeAccName", "关闭者" },
						{ "closeTime", "关闭时间" } });

		request.addModel("workbook", workbook);
		request.addModel("name", "BugList.xls");
		return "success";
	}

	@Path("/bugs/addtodo")
	public void addTODO(Request request) {

		int[] ids = Validator.toIntArray(request.getString("ids"));
		if (ids.length == 0) { return; }

		Map<Integer, Project> projects = new HashMap<>();
		Map<Integer, ProjectModel> modules = new HashMap<>();
		for (int id : ids) {

			Bug bug = Bug.load(id);
			if (bug == null) {
				continue;
			}
			UserTodo todo = new UserTodo();
			todo.setCreateTime(new Date());
			todo.setCreator(LoginUser.current().getUser().getId());
			todo.setStatus(TODO.PENDING);
			todo.setTitle("修改BUG:[#" + bug.getId() + " ]" + bug.getTitle());

			Project p = projects.get(bug.getProjectId());
			if (p == null) {
				p = Project.load(bug.getProjectId());
				projects.put(bug.getProjectId(), p);
			}
			if (p == null) {
				continue;
			}
			ProjectModel m = modules.get(bug.getModelId());
			if (m == null) {
				m = ProjectModel.load(bug.getModelId());
			}
			if (m == null) {
				continue;
			}

			todo.setRemark("项目：" + p.getName() + "\n模块:" + m.getName());

			todo.save();
		}
	}
}
